package com.cloud2eye.auth.cfg;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ytkj.aoms.auth.jwt.CommonUtil;
import com.ytkj.aoms.auth.jwt.TokenAuth;
import com.ytkj.aoms.auth.service.UserService;
import com.ytkj.aoms.http.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Slf4j
public class AuthenticationTokenFilter extends OncePerRequestFilter {
    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private TokenAuth tokenAuth;

    @Autowired
    private UserService userService;

    @Value("${jwt.header}")
    private String tokenHeader;

    @Value("${jwt.route.authentication.path}")
    private String authPath;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        String authToken = request.getHeader(this.tokenHeader);
        String username = tokenAuth.getUsernameFromToken(authToken);
        String ip = CommonUtil.getIpAddr(request);

//        log.info("checking authenticatiyson for user " + username + " from " + ip + " for resource " + request.getRequestURI());

        if(username!=null){
            if(!userService.isEnable(username)){
                printJson(response,new Result(-1,"unableUser",new JSONObject()));
                return;
            }
        }
        if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {//登录方法不会进入此语句
            UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
            if(!userService.isSameToken(username,authToken)){
                printJson(response,new Result(-1,"diffToken",new JSONObject()));
                return;
            }
            if (tokenAuth.validateToken(authToken, ip, userDetails)) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));


                logger.info("authenticated user " + username + " from "+ ip +", setting security context");
                SecurityContextHolder.getContext().setAuthentication(authentication);
               /* if(!userDetails.getAuthorities().contains(request.getServletPath())){
                    response.setContentType("text/html; charset=utf-8");
                    PrintWriter out = response.getWriter();
                    out.write(JSON.toJSONString(new Result().fail(-100,"没有访问权限")));
                    out.flush();
                    out.close();
                    return;
                }*/
            }
        }

        chain.doFilter(request, response);
    }
    private void printJson(HttpServletResponse response,Result result) throws IOException {
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.write(JSON.toJSONString(result));
        out.flush();
        out.close();
    }
}